/* 日历组件的循环渲染使用了太多的循环可能会影响性能， 多半需要优化 */
/* 房间的日期现在全部安YYYY-MM-DD处理，没有加入时分秒 */

<template>
  <CalendarBase ref="calendar" width="1400px" top="4vh !important" @date-panel-change="onRefresh"
                @cancel="onCancel">
    <!-- 日历操作栏 -->
    <template v-slot:calendar-month-action>
      <el-form :disabled="status__.DIALOG_STATUS === options__.DIALOG_TYPE.DETAIL">
        <el-button type="primary" @click="onSelectCurrentMonthAll()">全选当前月份</el-button>
        <el-button type="primary" @click="onSelectClearAll()">取消全部已选项</el-button>
        <el-button type="primary" @click="onBatchInitStockNum()">批量设置日历库存</el-button>
        <el-button type="primary" @click="onBatchClearStockNum()">批量清空日历库存</el-button>
      </el-form>

      <!-- 批量设置日历库存Dialog -->
      <batch-stock-edit-dialog></batch-stock-edit-dialog>
    </template>

    <!-- 日历内容栏 -->
    <template v-slot:calendar-month-item="slotProps">
      <div
        v-if="$dayjs(slotProps.date).format('YYYY-MM') === $dayjs(slotProps.currentDate).format('YYYY-MM')"
        class="ticket-stock-calendar-item-wapper"
        :class="{
          'selected': dayList[slotProps.index].selection,
          'can-not-selected': canBeEditCmp(slotProps.date)
        }"
      >
        <div class="one">
          <!-- 勾选项 -->
          <el-checkbox
            class="selection"
            :disabled="canBeEditCmp(slotProps.date) || status__.DIALOG_STATUS === options__.DIALOG_TYPE.DETAIL"
            v-model="dayList[slotProps.index].selection"
            @change="value => onSelectionChange(value, slotProps.date)"
          />

          <!-- 日期项 -->
          <span
            class="day"
            :class="{ 'today': $dayjs(slotProps.date).format('YYYY-MM-DD') === $dayjs().format('YYYY-MM-DD') }">
            {{ slotProps.date | getDateFilter }}
          </span>
        </div>

        <!-- 库存项 -->
        <div class="two">
          <!-- 未设置日历库存 -->
          <div v-if="!dayList[slotProps.index].stockNum" class="item">
            <span>日历库存：{{ dayList[slotProps.index].stockNum }}</span>
            <stock-edit-popover
              v-if="!canBeEditCmp(slotProps.date) && status__.DIALOG_STATUS !== options__.DIALOG_TYPE.DETAIL"
              :product-id="productId"
              :value="dayList[slotProps.index]"
              :can-show="['stockNum']">
            </stock-edit-popover>
          </div>

          <!-- 设置了库存日历 -->
          <div v-else>
            <!-- 日历库存余量 -->
            <div class="item">
              <span>库存余量：<span class="number">{{ dayList[slotProps.index].stockRemain }}</span></span>
              <stock-edit-popover
                v-if="!canBeEditCmp(slotProps.date) && status__.DIALOG_STATUS !== options__.DIALOG_TYPE.DETAIL"
                :product-id="productId"
                :value="dayList[slotProps.index]"
                :can-show="['stockRemain']">
              </stock-edit-popover>
              <i
                class="el-icon-delete"
                v-if="!canBeEditCmp(slotProps.date) && status__.DIALOG_STATUS !== options__.DIALOG_TYPE.DETAIL"
                style="margin-left: 5px; font-size: 16px;"
                @click="e => onClearStockRemain(slotProps.date)">
              </i>
            </div>

            <!-- 日历库存已售 -->
            <div class="item">
              <span>库存已售：<span class="number">{{ dayList[slotProps.index].calendarPurchaseNum }}</span></span>
            </div>
          </div>
        </div>
      </div>
    </template>
  </CalendarBase>
</template>

<script>
import StockEditPopover from './StockEditPopover'
import BatchStockEditDialog from './BatchStockEditDialog'
import CalendarBase from '../CalendarBase'

const DIALOG_TYPE = {
  CREATED: 'CREATED',
  DETAIL: 'DETAIL',
  UPDATE: 'UPDATE'
}

export default {
  components: {
    CalendarBase,
    StockEditPopover,
    BatchStockEditDialog
  },
  data () {
    return {
      productId: undefined,
      dayList: [], // 条目记录数据
      selectedSelections: new Set(), // 被勾选的条目，因为涉及跨月份勾选，所以需要记录, 需要去重
      status__: {
        DIALOG_STATUS: DIALOG_TYPE.CREATED
      },
      options__: {
        DIALOG_TYPE
      }
    }
  },
  filters: {
    getDateFilter (val) {
      const day = val.slice(-2)
      return parseInt(day)
    }
  },
  computed: {
    // 是否在可选择的时间范围内 - 即当前天  ~ 当前天 + 27天
    isCanSelectCmp () {
      return date => {
        const today = this.$dayjs()
        const current = this.$dayjs(date)
        return current.isAfter(today.add(-1, 'day')) && current.isBefore(today.add(24, 'day'))
      }
    },
    // 当前日之前的条目不能编辑
    canBeEditCmp () {
      return date => this.$dayjs(date).isBefore(this.$dayjs().add(-1, 'day'))
    }
  },
  mounted () {
    this.$bus.on('ticket-stock-calendar:open', params => this.onOpen(params, DIALOG_TYPE.UPDATE))
    this.$bus.on('ticket-stock-calendar:update', params => this.onOpen(params, DIALOG_TYPE.UPDATE))
    this.$bus.on('ticket-stock-calendar:detail', params => this.onOpen(params, DIALOG_TYPE.DETAIL))
    this.$bus.on('ticket-stock-calendar:refresh', this.onRefresh)
    this.$bus.on('ticket-stock-calendar:clearAllSelect', this.onSelectClearAll)
    this.dayListConstructor()
  },
  destroyed () {
    this.$bus.off('ticket-stock-calendar:open')
    this.$bus.off('ticket-stock-calendar:update')
    this.$bus.off('ticket-stock-calendar:detail')
  },
  methods: {
    // 事件 - open
    onOpen (id, type) {
      this.status__.DIALOG_STATUS = type
      this.productId = id
      this.getTicketStockCalendar()
      this.$refs.calendar.open()
    },

    // 事件 - 刷新
    onRefresh () {
      this.getTicketStockCalendar()
    },

    // bug - 解决dayList在未从后台获取回数据时, v-model绑定数组内变量， 空引用报错
    dayListConstructor () {
      const length = this.$refs.calendar.getDayList().length
      this.dayList = Array.from({ length }, (v, k) => ({}))
      return
    },

    onCancel () {
      // this.productId = undefined
      // // this.dayList = []
      this.selectedSelections.clear()

      // Object.assign(this.$data, this.$options.data.call(this))
    },

    // 获取库存日历列表
    getTicketStockCalendar () {
      const res = this.$refs.calendar.getDayList()
      const start = res[0]
      const end = res[res.length - 1]

      this.$POST('/sot-admin-api/product/repertory/queryCalendarStockList', {
        productId: this.productId,
        startUseDate: start,
        endUseDate: end
      }).then(({ data }) => {
        // 重置选中状态
        this.dayList = data.map(item => {
          item.selection = this.selectedSelections.has(item.useDate)
          return item
        })
      })
    },
    // 更新库存日历列表
    updateTicketStockCalendar (items) {
      return this.$POST('/sot-admin-api/product/repertory/updateBatchCalendarStock', {
        productId: this.productId,
        items
      })
    },
    // 事件 - 全选当前月份
    onSelectCurrentMonthAll () {
      const today = this.$dayjs()
      const date = this.$refs.calendar.getCurrentDate()
      this.dayList.map(item => {
        if (
          this.$dayjs(item.useDate).format('YYYY-MM') === this.$dayjs(date).format('YYYY-MM') // 是否是当前月
          && this.$dayjs(item.useDate).isAfter(today.add(-1, 'day')) // 日期是否早于今天
        ) {
          this.$set(item, 'selection', true)
          this.selectedSelections.add(item.useDate)
        }
      })
    },
    // 事件 - 条目被勾选
    onSelectionChange (status, date) {
      status
        // 勾选 - 添加
        ? this.selectedSelections.add(date)
        // 去勾选 - 删除
        : this.selectedSelections.delete(date)
    },
    // 事件 - 清除所有选中项目
    onSelectClearAll () {
      this.dayList.map(item => {
        this.$set(item, 'selection', false)
      })
      this.selectedSelections.clear()
    },
    // 事件 - 清除库存余量
    onClearStockRemain (date) {
      const match = [
        {
          useDate: date,
          stockRemain: null
        }
      ]

      this
      .updateTicketStockCalendar(match)
      .then(_ => {
        this.$swal.success('删除成功')
        this.onRefresh()
      })
    },
    // 事件 - 批量设置日历库存
    onBatchInitStockNum () {
      if (this.selectedSelections.size <= 0) {
        this.$swal.warning('请先勾选需要批量初始化的条目')
        return
      }

      this.$bus.emit('global:batch-stock-edit:open', {
        productId: this.productId,
        selectedSelections: this.selectedSelections
      })
    },

    // 事件 - 批量清除日历库存
    onBatchClearStockNum () {
      if (this.selectedSelections.size <= 0) {
        this.$swal.warning('请先勾选需要批量清除的条目')
        return
      }

      this.$confirm('是否确定清空选中的日历库存？清空后当前日不再执行日历库存。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const match = Array.from(this.selectedSelections).map(date => ({
          useDate: date,
          stockNum: null
        }))
        this
        .updateTicketStockCalendar(match)
        .then(_ => {
          this.$swal.success('批量清除日历库存成功')
          this.onRefresh()
          this.onSelectClearAll()
        })
      })
    }
  }
}
</script>

<style lang="scss">
.ticket-stock-calendar-item-wapper {
  &.selected {
    background-color: #4db6ac;
  }

  &.can-not-selected {
    background-color: #E4E7ED;
  }

  position: relative;
  padding: 15px;
  height: 100%;
  min-height: 80px;
  box-sizing: border-box;

  .one {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .day {
      width: 30px;
      height: 30px;
      color: #6a6b6d;
      font-size: 16px;
      text-align: center;
      line-height: 30px;
      font-weight: bold;
    }

    .today {
      color: #fff;
      background-color: #c63334;
      border-radius: 50%;
    }
  }

  .two {
    margin-top: 15px;
    color: #606266;
    font-size: 14px;
    display: flex;
    flex-flow: column;

    .item:not(:last-child) {
      margin-bottom: 10px;
    }

    .number {
      font-size: 16px;
    }
  }
}
</style>
